package com.sikhyeon.datastructure.controller;

import com.sikhyeon.datastructure.model.Queue;
import javafx.animation.FadeTransition;
import javafx.animation.TranslateTransition;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.io.IOException;

public class QueueController {

    @FXML
    private HBox queueContainer;

    @FXML
    private StackPane messagePane;

    @FXML
    private Label messageLabel;

    private Queue queue = new Queue();
    private int valueCounter = 1;

    public void goBack(ActionEvent event) throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/sikhyeon/datastructure/view/MainView.fxml"));
        Parent root = loader.load();
        Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
        Scene scene = new Scene(root, 800, 600); // 창 크기를 고정
        stage.setScene(scene);
        stage.show();
    }

    public void enqueueValue(ActionEvent event) {
        if (!queue.isFull() && queueContainer.getChildren().size() < Queue.MAX_SIZE) {
            int value = valueCounter++;
            queue.enqueue(value);
            addQueueElement(value);
        } else {
            showMessage("Queue overflow");
        }
    }

    public void dequeueValue(ActionEvent event) {
        if (!queue.isEmpty() && !queueContainer.getChildren().isEmpty()) {
            queue.dequeue();
            removeQueueElement();
        } else if (!queueContainer.getChildren().isEmpty()) {
            removeQueueElement();
        } else {
            showMessage("Queue underflow");
        }
    }

    private void addQueueElement(int value) {
        Rectangle rectangle = new Rectangle(50, 50, Color.LIGHTBLUE);
        Text text = new Text(String.valueOf(value));
        text.setFill(Color.BLACK);
        text.setTextAlignment(TextAlignment.CENTER);
        text.setX(rectangle.getX() + rectangle.getWidth() / 2 - text.getLayoutBounds().getWidth() / 2);
        text.setY(rectangle.getY() + rectangle.getHeight() / 2 + text.getLayoutBounds().getHeight() / 4);

        Group group = new Group();
        group.getChildren().addAll(rectangle, text);

        queueContainer.getChildren().add(group);

        TranslateTransition transition = new TranslateTransition(Duration.seconds(0.5), group);
        transition.setFromX(queueContainer.getWidth()); // 오른쪽에서 중앙으로 이동
        transition.setToX(0);
        transition.play();
    }

    private void removeQueueElement() {
        if (!queueContainer.getChildren().isEmpty()) {
            Node node = queueContainer.getChildren().get(0); // 맨 앞의 요소를 제거
            TranslateTransition transition = new TranslateTransition(Duration.seconds(0.5), node);
            transition.setToX(-queueContainer.getWidth()); // 왼쪽으로 이동하여 삭제
            transition.setOnFinished(e -> queueContainer.getChildren().remove(node));
            transition.play();
        }
    }

    public void resetQueue(ActionEvent event) {
        initialize();
    }

    public void initialize() {
        queue = new Queue();
        valueCounter = 1;
        queueContainer.getChildren().clear();
        showMessage("Queue initialized");
    }

    private void showMessage(String message) {
        messageLabel.setText(message);
        FadeTransition fadeIn = new FadeTransition(Duration.seconds(0.5), messagePane);
        fadeIn.setFromValue(0);
        fadeIn.setToValue(1);
        fadeIn.play();

        FadeTransition fadeOut = new FadeTransition(Duration.seconds(0.5), messagePane);
        fadeOut.setFromValue(1);
        fadeOut.setToValue(0);
        fadeOut.setDelay(Duration.seconds(1.5));
        fadeOut.play();
    }
}
